"""
简化的FastAPI接口

提供简洁的项目调度优化API服务，移除复杂的功能，专注于核心调度优化。
支持CSV文件上传，返回标准化的JSON响应格式。
"""

# 移除未使用的导入
from datetime import datetime
from typing import Any, Dict, List, Optional

import uvicorn
from fastapi import FastAPI, File, Form, HTTPException, UploadFile, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel, Field

from .error_handlers import get_current_timestamp, handle_scheduler_errors
from .exceptions import (
    DataParsingError,
    FileProcessingError,
    SchedulerError,
    ValidationError,
)
from .logging_config import APILogger, get_logger
from .simplified_scheduler_service import SimplifiedSchedulerService

# 初始化日志记录器
logger = get_logger("api")


# Pydantic模型定义
class SubdivisionConfigRequest(BaseModel):
    """分区配置请求"""
    
    subdivision_count: int = Field(2, ge=2, le=10, description="分区数量，范围2-10")
    resource_efficiency: float = Field(0.75, ge=0.1, le=1.0, description="资源效率，范围0.1-1.0")
    enable_subdivision: bool = Field(True, description="是否启用分区功能")


class WorkerTypeConfig(BaseModel):
    """工种配置"""
    
    name: str = Field(..., description="工种名称")
    capacity: int = Field(..., ge=1, description="工种容量")


class OptimizationConfigRequest(BaseModel):
    """优化配置请求"""
    
    subdivision_config: Optional[SubdivisionConfigRequest] = Field(None, description="分区配置")
    worker_types: Optional[List[WorkerTypeConfig]] = Field(None, description="工种配置")
    solve_time_limit: int = Field(300, ge=10, le=3600, description="求解时间限制（秒）")
    optimization_objective: str = Field("minimize_makespan", description="优化目标")


class OptimizationResult(BaseModel):
    """
    优化结果响应模型
    
    包含项目调度优化的完整结果信息，包括优化后的调度计划、
    工期对比、分区信息、工种分配等详细数据。
    """

    success: bool = Field(
        ..., 
        description="优化是否成功",
        example=True
    )
    makespan: Optional[int] = Field(
        None, 
        description="优化后的总工期（天）",
        example=45,
        ge=1
    )
    schedule: Optional[Any] = Field(
        None, 
        description="""
        详细调度计划，包含每个工序的开始时间、结束时间、分区信息等。
        格式为工序对象列表，每个工序包含：
        - id: 工序ID
        - name: 工序名称  
        - start_time: 开始时间
        - end_time: 结束时间
        - duration: 持续时间
        - subdivision: 所属分区
        - worker_allocation: 工种分配（如果有）
        """,
        example=[
            {
                "id": 1,
                "name": "基础开挖",
                "start_time": 0,
                "end_time": 5,
                "duration": 5,
                "subdivision": 1
            }
        ]
    )
    duration_comparison: Optional[Dict[str, Any]] = Field(
        None, 
        description="""
        工期对比信息，包含优化前后的工期对比和改进幅度。
        包含字段：
        - original_duration: 原始工期
        - optimized_duration: 优化后工期
        - improvement: 改进天数
        - improvement_percentage: 改进百分比
        """,
        example={
            "original_duration": 60,
            "optimized_duration": 45,
            "improvement": 15,
            "improvement_percentage": 25.0
        }
    )
    subdivision_info: Optional[Dict[str, Any]] = Field(
        None, 
        description="""
        分区处理信息，包含分区配置和处理结果。
        包含字段：
        - enabled: 是否启用分区
        - subdivision_count: 分区数量
        - activities_subdivided: 被分区的工序数量
        - resource_efficiency: 资源效率
        """,
        example={
            "enabled": True,
            "subdivision_count": 2,
            "activities_subdivided": 8,
            "resource_efficiency": 0.75
        }
    )
    worker_allocation: Optional[Dict[int, Any]] = Field(
        None, 
        description="""
        工种分配信息，按工序ID映射工种需求。
        格式为 {工序ID: {工种名称: 需求数量}}
        """,
        example={
            1: {"钢筋工": 5, "挖掘工": 3},
            2: {"泥工": 8, "架子工": 4}
        }
    )
    error_message: Optional[str] = Field(
        None, 
        description="错误信息（优化失败时提供）",
        example="数据解析失败：缺少必需列 'ID'"
    )
    solve_time: Optional[float] = Field(
        None, 
        description="求解耗时（秒）",
        example=12.5,
        ge=0
    )
    status: Optional[str] = Field(
        None, 
        description="""
        求解状态，可能的值：
        - OPTIMAL: 找到最优解
        - FEASIBLE: 找到可行解
        - INFEASIBLE: 无可行解
        - UNKNOWN: 求解状态未知
        """,
        example="OPTIMAL"
    )
    timestamp: str = Field(
        default_factory=lambda: datetime.now().isoformat(), 
        description="响应时间戳（ISO格式）",
        example="2024-01-15T10:30:00.123456"
    )


class HealthResponse(BaseModel):
    """
    健康检查响应模型
    
    用于系统健康状态监控和负载均衡器检查。
    """

    status: str = Field(
        "healthy", 
        description="""
        系统状态，可能的值：
        - healthy: 系统正常运行
        - degraded: 系统部分功能受限
        - unhealthy: 系统故障
        """,
        example="healthy"
    )
    version: str = Field(
        "2.0.0", 
        description="系统版本号",
        example="2.0.0"
    )
    timestamp: str = Field(
        default_factory=lambda: datetime.now().isoformat(), 
        description="健康检查时间戳（ISO格式）",
        example="2024-01-15T10:30:00.123456"
    )


class SystemInfo(BaseModel):
    """
    系统信息响应模型
    
    提供SchedulerAI系统的详细配置信息和能力说明。
    """

    name: str = Field(
        "SchedulerAI Simplified", 
        description="系统名称",
        example="SchedulerAI Simplified"
    )
    version: str = Field(
        "2.0.0", 
        description="系统版本号",
        example="2.0.0"
    )
    supported_formats: List[str] = Field(
        ["CSV"], 
        description="支持的文件格式列表",
        example=["CSV"]
    )
    optimization_objectives: List[str] = Field(
        ["minimize_makespan"], 
        description="""
        支持的优化目标列表：
        - minimize_makespan: 最小化项目总工期
        """,
        example=["minimize_makespan"]
    )
    max_activities: int = Field(
        10000, 
        description="系统支持的最大工序数量",
        example=10000,
        ge=1
    )
    default_resource_types: List[str] = Field(
        ["worker", "excavator", "crane"], 
        description="""
        默认支持的资源类型列表，用户可以在CSV文件中使用
        Resource_<类型名> 格式定义资源需求
        """,
        example=["worker", "excavator", "crane"]
    )


# 创建FastAPI应用
app = FastAPI(
    title="SchedulerAI 项目调度优化API",
    description="""
    ## SchedulerAI 项目调度优化API服务

    基于CP-SAT算法的智能项目调度优化系统，支持：
    
    ### 核心功能
    - 📊 **项目调度优化**: 基于约束满足的智能调度算法
    - 🔧 **工种资源管理**: 支持多种工种的容量约束配置
    - 📈 **分区优化**: 大型项目的分区处理和优化
    - 📋 **CSV数据导入**: 标准化的项目数据格式支持
    - 🎯 **多目标优化**: 支持工期最小化等多种优化目标
    
    ### 支持的文件格式
    - CSV文件（UTF-8, GBK, GB2312编码）
    - 必需列：ID, 名称, 工期, 前置任务
    - 可选列：划分条件, Resource_* (资源需求)
    
    ### API使用流程
    1. 准备符合格式要求的CSV项目文件
    2. 调用 `/api/v1/validate-csv` 验证文件格式
    3. 使用 `/api/v1/optimize` 或 `/api/v1/optimize-with-config` 执行优化
    4. 获取优化结果和调度计划
    
    ### 技术支持
    - 📧 技术支持: support@schedulerai.com
    - 📖 用户手册: [查看完整文档](/static/docs/user-manual.html)
    - 🔧 故障排除: [常见问题解答](/static/docs/troubleshooting.html)
    """,
    version="2.0.0",
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_tags=[
        {
            "name": "系统信息",
            "description": "系统健康检查和基本信息查询接口"
        },
        {
            "name": "数据验证",
            "description": "CSV文件格式验证和数据质量检查接口"
        },
        {
            "name": "调度优化",
            "description": "项目调度优化的核心接口，支持基础优化和高级配置优化"
        }
    ],
    contact={
        "name": "SchedulerAI技术支持",
        "email": "support@schedulerai.com",
        "url": "https://schedulerai.com/support"
    },
    license_info={
        "name": "商业许可证",
        "url": "https://schedulerai.com/license"
    }
)

# 配置CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:3000",  # React开发服务器
        "http://127.0.0.1:3000",
        "http://localhost:3001",  # 额外的React端口
        "http://127.0.0.1:3001",
        "http://localhost:3002",  # 前端应用端口
        "http://127.0.0.1:3002",
        "http://localhost:5173",  # Vite开发服务器
        "http://127.0.0.1:5173",
        "http://localhost:8080",  # 其他可能的前端端口
        "http://127.0.0.1:8080",
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allow_headers=["*"],
)

# 挂载静态文件服务（用于文档和示例）
try:
    app.mount("/static", StaticFiles(directory="docs"), name="static")
except Exception:
    # 如果docs目录不存在，忽略错误
    pass


# 全局服务实例
scheduler_service = SimplifiedSchedulerService()

# 自定义文档页面
@app.get("/docs-zh", response_class=HTMLResponse, include_in_schema=False)
async def custom_docs_zh():
    """中文API文档页面"""
    return """
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SchedulerAI API 文档</title>
        <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.52.5/swagger-ui.css" />
        <style>
            .swagger-ui .topbar { display: none; }
            .swagger-ui .info .title { color: #3b4151; }
            .swagger-ui .scheme-container { background: #f7f7f7; padding: 10px; }
        </style>
    </head>
    <body>
        <div id="swagger-ui"></div>
        <script src="https://unpkg.com/swagger-ui-dist@3.52.5/swagger-ui-bundle.js"></script>
        <script>
            SwaggerUIBundle({
                url: '/openapi.json',
                dom_id: '#swagger-ui',
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIBundle.presets.standalone
                ],
                layout: "BaseLayout",
                deepLinking: true,
                showExtensions: true,
                showCommonExtensions: true,
                defaultModelsExpandDepth: 2,
                defaultModelExpandDepth: 2,
                docExpansion: "list",
                filter: true,
                tryItOutEnabled: true,
                requestInterceptor: function(request) {
                    // 可以在这里添加请求拦截逻辑
                    return request;
                },
                responseInterceptor: function(response) {
                    // 可以在这里添加响应拦截逻辑
                    return response;
                }
            });
        </script>
    </body>
    </html>
    """

@app.get("/api-guide", response_class=HTMLResponse, include_in_schema=False)
async def api_guide():
    """API使用指南页面"""
    return """
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SchedulerAI API 使用指南</title>
        <style>
            body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
            .container { max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
            h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; }
            h2 { color: #34495e; margin-top: 30px; }
            .endpoint { background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 15px 0; border-left: 4px solid #007bff; }
            .method { display: inline-block; padding: 4px 8px; border-radius: 3px; color: white; font-weight: bold; margin-right: 10px; }
            .get { background: #28a745; }
            .post { background: #007bff; }
            code { background: #f1f1f1; padding: 2px 6px; border-radius: 3px; font-family: 'Courier New', monospace; }
            pre { background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; border: 1px solid #e9ecef; }
            .example { background: #e8f5e8; padding: 15px; border-radius: 5px; margin: 10px 0; }
            .nav { background: #343a40; padding: 15px; margin: -30px -30px 30px -30px; border-radius: 8px 8px 0 0; }
            .nav a { color: white; text-decoration: none; margin-right: 20px; padding: 8px 16px; border-radius: 4px; }
            .nav a:hover { background: #495057; }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="nav">
                <a href="/docs">Swagger UI</a>
                <a href="/redoc">ReDoc</a>
                <a href="/docs-zh">中文文档</a>
                <a href="/api-guide">使用指南</a>
                <a href="/static/API_REFERENCE.md" target="_blank">完整文档</a>
            </div>
            
            <h1>🚀 SchedulerAI API 快速使用指南</h1>
            
            <h2>📋 API概述</h2>
            <p>SchedulerAI 提供基于 CP-SAT 算法的智能项目调度优化服务，支持工种约束、分区优化等高级功能。</p>
            
            <h2>🔗 核心接口</h2>
            
            <div class="endpoint">
                <span class="method get">GET</span><strong>/health</strong>
                <p>系统健康检查，用于监控服务状态</p>
                <div class="example">
                    <strong>示例:</strong><br>
                    <code>curl http://localhost:8000/health</code>
                </div>
            </div>
            
            <div class="endpoint">
                <span class="method post">POST</span><strong>/api/v1/validate-csv</strong>
                <p>验证CSV文件格式和数据完整性</p>
                <div class="example">
                    <strong>示例:</strong><br>
                    <code>curl -X POST -F "csv_file=@project.csv" http://localhost:8000/api/v1/validate-csv</code>
                </div>
            </div>
            
            <div class="endpoint">
                <span class="method post">POST</span><strong>/api/v1/optimize</strong>
                <p>基础项目调度优化（使用默认配置）</p>
                <div class="example">
                    <strong>示例:</strong><br>
                    <code>curl -X POST -F "csv_file=@project.csv" http://localhost:8000/api/v1/optimize</code>
                </div>
            </div>
            
            <div class="endpoint">
                <span class="method post">POST</span><strong>/api/v1/optimize-with-config</strong>
                <p>高级项目调度优化（支持自定义配置）</p>
                <div class="example">
                    <strong>示例:</strong><br>
                    <pre>curl -X POST \\
  -F "csv_file=@project.csv" \\
  -F 'config={"solve_time_limit":600,"worker_types":[{"name":"钢筋工","capacity":20}]}' \\
  http://localhost:8000/api/v1/optimize-with-config</pre>
                </div>
            </div>
            
            <h2>📊 CSV文件格式要求</h2>
            <p>上传的CSV文件必须包含以下列：</p>
            <ul>
                <li><strong>ID</strong>: 工序编号（整数）</li>
                <li><strong>名称</strong> 或 <strong>Name</strong>: 工序名称</li>
                <li><strong>工期</strong> 或 <strong>Duration</strong>: 工序持续时间（天）</li>
                <li><strong>前置任务</strong> 或 <strong>Predecessors</strong>: 前置工序ID，多个用逗号分隔</li>
            </ul>
            
            <p>可选列：</p>
            <ul>
                <li><strong>划分条件</strong>: 是否可分区（"是"/"否"）</li>
                <li><strong>Resource_Worker</strong>: 工人需求数量</li>
                <li><strong>Resource_Excavator</strong>: 挖掘机需求数量</li>
                <li><strong>Resource_*</strong>: 其他资源需求列</li>
            </ul>
            
            <h2>🛠️ 配置参数说明</h2>
            <pre>{
  "solve_time_limit": 600,           // 求解时间限制（秒）
  "subdivision_config": {
    "subdivision_count": 3,          // 分区数量（2-10）
    "resource_efficiency": 0.85,     // 资源效率（0.1-1.0）
    "enable_subdivision": true       // 是否启用分区
  },
  "worker_types": [
    {"name": "钢筋工", "capacity": 20},  // 工种配置
    {"name": "泥工", "capacity": 15}
  ]
}</pre>
            
            <h2>🔧 故障排除</h2>
            <ul>
                <li><strong>文件上传失败</strong>: 检查文件格式是否为CSV，大小是否超过10MB</li>
                <li><strong>优化失败</strong>: 检查前置关系是否存在循环依赖</li>
                <li><strong>求解时间过长</strong>: 尝试增加分区数量或减少工序数量</li>
                <li><strong>无可行解</strong>: 检查资源约束是否过于严格</li>
            </ul>
            
            <h2>📞 技术支持</h2>
            <p>如需帮助，请联系：</p>
            <ul>
                <li>📧 邮箱: support@schedulerai.com</li>
                <li>📖 完整文档: <a href="/static/API_REFERENCE.md" target="_blank">API参考文档</a></li>
                <li>🔧 故障排除: <a href="/static/TROUBLESHOOTING.md" target="_blank">故障排除指南</a></li>
            </ul>
        </div>
    </body>
    </html>
    """


# API端点实现
@app.get(
    "/health", 
    response_model=HealthResponse,
    tags=["系统信息"],
    summary="系统健康检查",
    description="""
    检查SchedulerAI系统的运行状态和基本信息。
    
    ### 用途
    - 监控系统是否正常运行
    - 获取系统版本信息
    - 用于负载均衡器的健康检查
    
    ### 响应说明
    - `status`: 系统状态，"healthy"表示正常
    - `version`: 当前系统版本号
    - `timestamp`: 检查时间戳
    
    ### 使用示例
    ```bash
    curl -X GET "http://localhost:8000/health"
    ```
    """,
    responses={
        200: {
            "description": "系统运行正常",
            "content": {
                "application/json": {
                    "example": {
                        "status": "healthy",
                        "version": "2.0.0",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        }
    }
)
async def health_check():
    """系统健康检查"""
    return HealthResponse()


@app.get(
    "/api/v1/info", 
    response_model=SystemInfo,
    tags=["系统信息"],
    summary="系统信息查询",
    description="""
    获取SchedulerAI系统的详细配置信息和能力说明。
    
    ### 功能说明
    - 查询系统支持的文件格式
    - 获取优化算法的配置参数
    - 了解系统的处理能力限制
    
    ### 返回信息
    - `name`: 系统名称
    - `version`: 系统版本
    - `supported_formats`: 支持的文件格式列表
    - `optimization_objectives`: 支持的优化目标
    - `max_activities`: 最大支持的工序数量
    - `default_resource_types`: 默认资源类型
    
    ### 使用示例
    ```bash
    curl -X GET "http://localhost:8000/api/v1/info"
    ```
    """,
    responses={
        200: {
            "description": "系统信息查询成功",
            "content": {
                "application/json": {
                    "example": {
                        "name": "SchedulerAI Simplified",
                        "version": "2.0.0",
                        "supported_formats": ["CSV"],
                        "optimization_objectives": ["minimize_makespan"],
                        "max_activities": 10000,
                        "default_resource_types": ["worker", "excavator", "crane"]
                    }
                }
            }
        }
    }
)
async def system_info():
    """系统信息查询"""
    return SystemInfo()


@app.post(
    "/api/v1/optimize", 
    response_model=OptimizationResult,
    tags=["调度优化"],
    summary="项目调度优化（默认配置）",
    description="""
    使用默认配置执行项目调度优化，适用于快速优化场景。
    
    ### 功能特点
    - 🚀 **快速优化**: 使用预设的最佳配置参数
    - 📊 **智能调度**: 基于CP-SAT约束满足算法
    - 🔄 **自动分区**: 支持大型项目的智能分区处理
    - 📈 **工期优化**: 自动最小化项目总工期
    
    ### CSV文件格式要求
    
    #### 必需列
    - `ID`: 工序编号（整数）
    - `名称` 或 `Name`: 工序名称（字符串）
    - `工期` 或 `Duration`: 工序持续时间（整数，单位：天）
    - `前置任务` 或 `Predecessors`: 前置工序ID，多个用逗号分隔
    
    #### 可选列
    - `划分条件`: 是否可分区（"是"/"否"）
    - `Resource_Worker`: 工人需求数量
    - `Resource_Excavator`: 挖掘机需求数量
    - `Resource_Crane`: 起重机需求数量
    - `Resource_*`: 其他资源需求列
    
    ### 默认配置参数
    - 求解时间限制：300秒
    - 分区数量：2个分区
    - 资源效率：75%
    - 优化目标：最小化工期
    
    ### 使用示例
    
    #### cURL示例
    ```bash
    curl -X POST "http://localhost:8000/api/v1/optimize" \\
         -H "Content-Type: multipart/form-data" \\
         -F "csv_file=@project_data.csv"
    ```
    
    #### Python示例
    ```python
    import requests
    
    with open('project_data.csv', 'rb') as f:
        response = requests.post(
            'http://localhost:8000/api/v1/optimize',
            files={'csv_file': f}
        )
    result = response.json()
    print(f"优化工期: {result['makespan']}天")
    ```
    
    #### JavaScript示例
    ```javascript
    const formData = new FormData();
    formData.append('csv_file', fileInput.files[0]);
    
    fetch('/api/v1/optimize', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log('优化结果:', data));
    ```
    """,
    responses={
        200: {
            "description": "优化成功",
            "content": {
                "application/json": {
                    "example": {
                        "success": True,
                        "makespan": 45,
                        "schedule": [
                            {
                                "id": 1,
                                "name": "基础开挖",
                                "start_time": 0,
                                "end_time": 5,
                                "duration": 5,
                                "subdivision": 1
                            }
                        ],
                        "duration_comparison": {
                            "original_duration": 60,
                            "optimized_duration": 45,
                            "improvement": 15,
                            "improvement_percentage": 25.0
                        },
                        "subdivision_info": {
                            "enabled": True,
                            "subdivision_count": 2,
                            "activities_subdivided": 8
                        },
                        "solve_time": 12.5,
                        "status": "OPTIMAL",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        },
        400: {
            "description": "请求错误",
            "content": {
                "application/json": {
                    "example": {
                        "success": False,
                        "error_message": "CSV文件格式错误：缺少必需列 'ID'",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        },
        422: {
            "description": "文件验证失败",
            "content": {
                "application/json": {
                    "example": {
                        "success": False,
                        "error_message": "只支持CSV文件格式",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        }
    }
)
@handle_scheduler_errors
async def optimize_schedule(
    csv_file: UploadFile = File(
        ..., 
        description="包含项目数据的CSV文件，支持UTF-8/GBK/GB2312编码",
        media_type="text/csv"
    )
):
    """
    项目调度优化API（简化版，使用默认配置）

    上传CSV文件，返回优化后的调度结果和工期对比信息。

    Args:
        csv_file: 包含项目数据的CSV文件，必须包含以下列：
            - ID: 工序编号
            - Name/名称: 工序名称
            - Duration/工期: 工序工期
            - Predecessors/前置任务: 前置关系
            - 划分条件: 是否可分区（"是"或"否"）
            - Resource_*: 资源需求列（如Resource_Worker, Resource_Excavator）

    Returns:
        优化结果，包含调度计划、工期对比等信息
    """
    # 创建API日志记录器
    api_logger = APILogger("/api/v1/optimize")
    api_logger.log_request(filename=csv_file.filename, size=csv_file.size)

    # 读取和解析CSV文件
    csv_text = await _read_csv_file(csv_file)

    # 使用默认配置执行优化
    result = scheduler_service.optimize_schedule(csv_text, None)

    # 记录API响应
    api_logger.log_response(
        success=result["success"],
        makespan=result.get("makespan"),
        solve_time=result.get("solve_time"),
    )

    # 构建响应
    return OptimizationResult(
        success=result["success"],
        makespan=result.get("makespan"),
        schedule=result.get("schedule"),
        duration_comparison=result.get("duration_comparison"),
        subdivision_info=result.get("subdivision_info"),
        worker_allocation=result.get("worker_allocation"),
        error_message=result.get("error_message"),
        solve_time=result.get("solve_time"),
        status=result.get("status"),
    )


@app.post(
    "/api/v1/optimize-with-config", 
    response_model=OptimizationResult,
    tags=["调度优化"],
    summary="项目调度优化（自定义配置）",
    description="""
    使用自定义配置执行项目调度优化，支持高级参数调整。
    
    ### 高级功能
    - ⚙️ **自定义配置**: 支持分区、工种、求解参数的精细调整
    - 👷 **工种管理**: 配置不同工种的容量约束
    - 📊 **分区优化**: 自定义分区数量和资源效率
    - 🎯 **多目标**: 支持不同的优化目标设置
    
    ### 配置参数格式
    
    config参数应为JSON字符串，包含以下可选字段：
    
    ```json
    {
        "solve_time_limit": 300,
        "optimization_objective": "minimize_makespan",
        "subdivision_config": {
            "subdivision_count": 3,
            "resource_efficiency": 0.8,
            "enable_subdivision": true
        },
        "worker_types": [
            {"name": "钢筋工", "capacity": 15},
            {"name": "泥工", "capacity": 12},
            {"name": "架子工", "capacity": 10}
        ]
    }
    ```
    
    ### 配置参数说明
    
    #### 基础配置
    - `solve_time_limit`: 求解时间限制（秒），范围10-3600
    - `optimization_objective`: 优化目标，目前支持"minimize_makespan"
    
    #### 分区配置 (subdivision_config)
    - `subdivision_count`: 分区数量，范围2-10
    - `resource_efficiency`: 资源效率，范围0.1-1.0
    - `enable_subdivision`: 是否启用分区功能
    
    #### 工种配置 (worker_types)
    - `name`: 工种名称（字符串）
    - `capacity`: 工种容量（正整数）
    
    ### 默认工种配置
    如果未提供工种配置，系统将使用以下默认值：
    - 钢筋工: 12人
    - 泥工: 10人  
    - 架子工: 12人
    - 模板工: 20人
    - 电工: 2人
    - 焊工: 2人
    - 起重工: 2人
    - 通用工人: 5人
    - 挖掘工: 8人
    
    ### 使用示例
    
    #### cURL示例
    ```bash
    curl -X POST "http://localhost:8000/api/v1/optimize-with-config" \\
         -H "Content-Type: multipart/form-data" \\
         -F "csv_file=@project_data.csv" \\
         -F 'config={"solve_time_limit":600,"worker_types":[{"name":"钢筋工","capacity":20}]}'
    ```
    
    #### Python示例
    ```python
    import requests
    import json
    
    config = {
        "solve_time_limit": 600,
        "subdivision_config": {
            "subdivision_count": 3,
            "resource_efficiency": 0.85,
            "enable_subdivision": True
        },
        "worker_types": [
            {"name": "钢筋工", "capacity": 20},
            {"name": "泥工", "capacity": 15}
        ]
    }
    
    with open('project_data.csv', 'rb') as f:
        response = requests.post(
            'http://localhost:8000/api/v1/optimize-with-config',
            files={'csv_file': f},
            data={'config': json.dumps(config)}
        )
    result = response.json()
    ```
    
    #### JavaScript示例
    ```javascript
    const config = {
        solve_time_limit: 600,
        worker_types: [
            {name: "钢筋工", capacity: 20},
            {name: "泥工", capacity: 15}
        ]
    };
    
    const formData = new FormData();
    formData.append('csv_file', fileInput.files[0]);
    formData.append('config', JSON.stringify(config));
    
    fetch('/api/v1/optimize-with-config', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log('优化结果:', data));
    ```
    """,
    responses={
        200: {
            "description": "优化成功",
            "content": {
                "application/json": {
                    "example": {
                        "success": True,
                        "makespan": 42,
                        "schedule": [
                            {
                                "id": 1,
                                "name": "基础开挖",
                                "start_time": 0,
                                "end_time": 5,
                                "duration": 5,
                                "subdivision": 1,
                                "worker_allocation": {
                                    "钢筋工": 5,
                                    "挖掘工": 3
                                }
                            }
                        ],
                        "duration_comparison": {
                            "original_duration": 60,
                            "optimized_duration": 42,
                            "improvement": 18,
                            "improvement_percentage": 30.0
                        },
                        "subdivision_info": {
                            "enabled": True,
                            "subdivision_count": 3,
                            "activities_subdivided": 12,
                            "resource_efficiency": 0.85
                        },
                        "worker_allocation": {
                            1: {"钢筋工": 5, "挖掘工": 3},
                            2: {"泥工": 8, "架子工": 4}
                        },
                        "solve_time": 25.8,
                        "status": "OPTIMAL",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        },
        400: {
            "description": "配置参数错误",
            "content": {
                "application/json": {
                    "example": {
                        "success": False,
                        "error_message": "配置参数格式错误: JSON解析失败",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        }
    }
)
@handle_scheduler_errors
async def optimize_schedule_with_config(
    csv_file: UploadFile = File(
        ..., 
        description="包含项目数据的CSV文件，支持UTF-8/GBK/GB2312编码",
        media_type="text/csv"
    ),
    config: str = Form(
        None, 
        description="优化配置JSON字符串，包含分区配置、工种配置等参数",
        example='{"solve_time_limit":600,"worker_types":[{"name":"钢筋工","capacity":20}]}'
    )
):
    """
    项目调度优化API（支持自定义配置）

    上传CSV文件并提供优化配置，返回优化后的调度结果。

    Args:
        csv_file: 包含项目数据的CSV文件
        config: 优化配置参数，包括分区配置、工种配置等

    Returns:
        优化结果，包含调度计划、工期对比、分区信息等
    """
    # 创建API日志记录器
    api_logger = APILogger("/api/v1/optimize-with-config")
    api_logger.log_request(filename=csv_file.filename, size=csv_file.size)

    # 读取和解析CSV文件
    csv_text = await _read_csv_file(csv_file)

    # 构建优化配置
    optimization_config = None
    if config:
        try:
            import json
            config_dict = json.loads(config)
            optimization_config = _build_optimization_config_from_dict(config_dict)
            logger.info(f"API接收到配置参数: {config_dict}")
            logger.info(f"处理后的优化配置: {optimization_config}")
        except json.JSONDecodeError as e:
            logger.error(f"配置JSON解析失败: {e}")
            raise HTTPException(status_code=400, detail=f"配置参数格式错误: {str(e)}")
        except Exception as e:
            logger.error(f"配置处理失败: {e}")
            raise HTTPException(status_code=400, detail=f"配置参数处理失败: {str(e)}")
    else:
        logger.info("未提供配置参数，将使用默认配置")

    # 如果没有提供工种配置，使用默认配置
    if not optimization_config or "worker_capacities" not in optimization_config:
        default_worker_capacities = {
            "钢筋工": 12,
            "泥工": 10,
            "架子工": 12,
            "模板工": 20,
            "电工": 2,
            "焊工": 2,
            "起重工": 2,
            "通用工人": 5,
            "挖掘工": 8,  # 添加挖掘工默认配置
        }
        if not optimization_config:
            optimization_config = {}
        optimization_config["worker_capacities"] = default_worker_capacities
        logger.info(f"使用默认工种配置: {default_worker_capacities}")

    # 执行优化
    result = scheduler_service.optimize_schedule(csv_text, optimization_config)

    # 记录API响应
    api_logger.log_response(
        success=result["success"],
        makespan=result.get("makespan"),
        solve_time=result.get("solve_time"),
    )

    # 构建响应
    return OptimizationResult(
        success=result["success"],
        makespan=result.get("makespan"),
        schedule=result.get("schedule"),
        duration_comparison=result.get("duration_comparison"),
        subdivision_info=result.get("subdivision_info"),
        worker_allocation=result.get("worker_allocation"),
        error_message=result.get("error_message"),
        solve_time=result.get("solve_time"),
        status=result.get("status"),
    )


@app.post(
    "/api/v1/validate-csv",
    tags=["数据验证"],
    summary="CSV文件格式验证",
    description="""
    验证CSV文件格式和数据质量，在执行优化前检查数据完整性。
    
    ### 验证功能
    - 📋 **格式检查**: 验证必需列是否存在
    - 📊 **数据统计**: 提供工序、前置关系等统计信息
    - 🔍 **质量分析**: 检查数据完整性和合理性
    - 💡 **优化建议**: 提供数据改进建议
    
    ### 验证项目
    
    #### 必需列检查
    - `ID`: 工序编号列
    - `名称` 或 `Name`: 工序名称列
    - `工期` 或 `Duration`: 工序持续时间列
    - `前置任务` 或 `Predecessors`: 前置关系列
    
    #### 可选列检查
    - `划分条件`: 分区标识列
    - `Resource_*`: 资源需求列
    
    #### 数据质量检查
    - 工序数量统计
    - 前置关系完整性
    - 可分区工序比例
    - 资源配置情况
    
    ### 验证结果说明
    
    #### 统计信息 (statistics)
    - `total_activities`: 总工序数量
    - `total_precedences`: 前置关系数量
    - `subdividable_activities`: 可分区工序数量
    - `resource_types`: 资源类型列表
    - `activities_with_resources`: 有资源需求的工序数量
    
    #### 验证结果 (validation_results)
    - `has_required_columns`: 是否包含必需列
    - `has_subdivision_column`: 是否包含分区列
    - `has_resource_columns`: 是否包含资源列
    - `has_precedences`: 是否包含前置关系
    
    #### 优化建议 (recommendations)
    - 数据质量改进建议
    - 优化配置推荐
    - 潜在问题提醒
    
    ### 使用示例
    
    #### cURL示例
    ```bash
    curl -X POST "http://localhost:8000/api/v1/validate-csv" \\
         -H "Content-Type: multipart/form-data" \\
         -F "csv_file=@project_data.csv"
    ```
    
    #### Python示例
    ```python
    import requests
    
    with open('project_data.csv', 'rb') as f:
        response = requests.post(
            'http://localhost:8000/api/v1/validate-csv',
            files={'csv_file': f}
        )
    
    result = response.json()
    if result['success']:
        print(f"验证通过，共{result['statistics']['total_activities']}个工序")
        for suggestion in result['recommendations']:
            print(f"建议: {suggestion}")
    ```
    
    #### JavaScript示例
    ```javascript
    const formData = new FormData();
    formData.append('csv_file', fileInput.files[0]);
    
    fetch('/api/v1/validate-csv', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            console.log('验证通过:', data.statistics);
            data.recommendations.forEach(rec => 
                console.log('建议:', rec)
            );
        }
    });
    ```
    """,
    responses={
        200: {
            "description": "验证完成",
            "content": {
                "application/json": {
                    "example": {
                        "success": True,
                        "file_info": {
                            "filename": "project_data.csv",
                            "size": 2048
                        },
                        "statistics": {
                            "total_activities": 25,
                            "total_precedences": 18,
                            "subdividable_activities": 12,
                            "resource_types": ["Worker", "Excavator", "Crane"],
                            "activities_with_resources": 20
                        },
                        "validation_results": {
                            "has_required_columns": True,
                            "has_subdivision_column": True,
                            "has_resource_columns": True,
                            "has_precedences": True
                        },
                        "recommendations": [
                            "CSV文件格式良好，可以进行调度优化",
                            "可分区工序比例适中，分区优化效果较好"
                        ],
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        },
        400: {
            "description": "验证失败",
            "content": {
                "application/json": {
                    "example": {
                        "success": False,
                        "error_message": "CSV文件格式错误：缺少必需列 'ID'",
                        "timestamp": "2024-01-15T10:30:00.123456"
                    }
                }
            }
        }
    }
)
@handle_scheduler_errors
async def validate_csv_file(
    csv_file: UploadFile = File(
        ..., 
        description="要验证的CSV文件，支持UTF-8/GBK/GB2312编码",
        media_type="text/csv"
    )
):
    """
    验证CSV文件格式

    检查CSV文件是否包含必需的列，并提供格式建议。

    Args:
        csv_file: 要验证的CSV文件

    Returns:
        验证结果和建议
    """
    # 创建API日志记录器
    api_logger = APILogger("/api/v1/validate-csv")
    api_logger.log_request(filename=csv_file.filename, size=csv_file.size)

    # 读取和解析CSV文件
    csv_text = await _read_csv_file(csv_file)

    # 使用数据解析器验证文件
    from .simplified_data_parser import SimplifiedDataParser

    parser = SimplifiedDataParser()

    # 尝试解析数据
    project_data = parser.parse_csv_data(csv_text)

    # 统计信息
    activities = project_data["activities"]
    precedences = project_data["precedences"]
    resources = project_data["resources"]
    resource_demands = project_data["resource_demands"]

    subdividable_count = sum(
        1 for act in activities if act.get("can_subdivide", False)
    )

    result = {
        "success": True,
        "file_info": {"filename": csv_file.filename, "size": len(csv_text)},
        "statistics": {
            "total_activities": len(activities),
            "total_precedences": len(precedences),
            "subdividable_activities": subdividable_count,
            "resource_types": list(resources.keys()),
            "activities_with_resources": len(resource_demands),
        },
        "validation_results": {
            "has_required_columns": True,
            "has_subdivision_column": subdividable_count > 0,
            "has_resource_columns": len(resources) > 0,
            "has_precedences": len(precedences) > 0,
        },
        "recommendations": _generate_validation_recommendations(
            len(activities), subdividable_count, len(resources), len(precedences)
        ),
        "timestamp": datetime.now().isoformat(),
    }

    # 记录API响应
    api_logger.log_response(
        success=True,
        total_activities=len(activities),
        subdividable_activities=subdividable_count,
    )

    return result


async def _read_csv_file(csv_file: UploadFile) -> str:
    """
    读取和解析CSV文件
    
    Args:
        csv_file: 上传的CSV文件
        
    Returns:
        CSV文件内容字符串
        
    Raises:
        FileProcessingError: 文件处理失败时
    """
    # 验证文件类型
    if not csv_file.filename.lower().endswith(".csv"):
        raise FileProcessingError("只支持CSV文件格式", file_name=csv_file.filename)

    # 读取CSV文件内容
    csv_content = await csv_file.read()
    csv_text = None

    # 尝试多种编码解析文件
    for encoding in ["utf-8", "gbk", "gb2312"]:
        try:
            csv_text = csv_content.decode(encoding)
            logger.info(f"成功使用{encoding}编码解析CSV文件")
            break
        except UnicodeDecodeError:
            continue

    if csv_text is None:
        raise FileProcessingError(
            "无法解析CSV文件编码，请确保文件为UTF-8、GBK或GB2312编码",
            file_name=csv_file.filename,
        )
    
    return csv_text


def _build_optimization_config_from_dict(config_dict: Dict[str, Any]) -> Dict[str, Any]:
    """
    从字典构建优化配置
    
    Args:
        config_dict: 配置字典
        
    Returns:
        优化配置字典
    """
    optimization_config = {
        "solve_time_limit": config_dict.get("solve_time_limit", 300),
        "optimization_objective": config_dict.get("optimization_objective", "minimize_makespan"),
    }
    
    # 构建分区配置
    subdivision_config = config_dict.get("subdivision_config", {})
    if subdivision_config:
        optimization_config["subdivision_config"] = {
            "subdivision_count": subdivision_config.get("subdivision_count", 2),
            "resource_efficiency": subdivision_config.get("resource_efficiency", 0.75),
            "enable_subdivision": subdivision_config.get("enable_subdivision", False),
        }
    
    # 构建工种配置 - 增强版本
    worker_types = config_dict.get("worker_types", [])
    if worker_types:
        # 转换为工种容量字典
        worker_capacities = {}
        for worker_config in worker_types:
            if isinstance(worker_config, dict) and "name" in worker_config and "capacity" in worker_config:
                name = worker_config["name"]
                capacity = worker_config["capacity"]
                
                # 验证容量值
                if isinstance(capacity, (int, float)) and capacity > 0:
                    worker_capacities[name] = int(capacity)
                    logger.info(f"API解析工种配置: {name} = {capacity}")
                else:
                    logger.warning(f"工种 {name} 的容量值无效: {capacity}，跳过")
        
        if worker_capacities:
            optimization_config["worker_capacities"] = worker_capacities
            logger.info(f"API设置工种容量配置: {worker_capacities}")
        else:
            logger.warning("工种配置解析后为空，将使用默认配置")
    else:
        logger.info("未提供工种配置，将在后续使用默认配置")
    
    return optimization_config

def _build_optimization_config(config_request: OptimizationConfigRequest) -> Dict[str, Any]:
    """
    构建优化配置字典
    
    Args:
        config_request: 优化配置请求
        
    Returns:
        优化配置字典
    """
    from .simplified_data_models import ResourceCapacity, SubdivisionConfig
    
    config_dict = {
        "solve_time_limit": config_request.solve_time_limit,
        "optimization_objective": config_request.optimization_objective,
    }
    
    # 构建分区配置
    if config_request.subdivision_config:
        subdivision_config = {
            "subdivision_count": config_request.subdivision_config.subdivision_count,
            "resource_efficiency": config_request.subdivision_config.resource_efficiency,
            "enable_subdivision": config_request.subdivision_config.enable_subdivision,
        }
        config_dict["subdivision_config"] = subdivision_config
    
    # 构建工种配置
    if config_request.worker_types:
        worker_types = []
        for worker_config in config_request.worker_types:
            worker_types.append({
                "name": worker_config.name,
                "capacity": worker_config.capacity
            })
        config_dict["worker_types"] = worker_types
    
    return config_dict


def _generate_validation_recommendations(
    activity_count: int,
    subdividable_count: int,
    resource_type_count: int,
    precedence_count: int,
) -> List[str]:
    """生成验证建议"""
    recommendations = []

    if activity_count == 0:
        recommendations.append("CSV文件中没有发现有效的工序数据")
    elif activity_count < 5:
        recommendations.append("工序数量较少，优化效果可能有限")
    elif activity_count > 1000:
        recommendations.append("工序数量较多，求解时间可能较长，建议增加求解时间限制")

    if subdividable_count == 0:
        recommendations.append("没有发现可分区的工序，请检查'划分条件'列是否正确设置")
    elif subdividable_count < activity_count * 0.2:
        recommendations.append("可分区工序比例较低，分区优化效果可能有限")

    if resource_type_count == 0:
        recommendations.append("没有发现资源需求信息，将使用默认资源配置")
    elif resource_type_count > 10:
        recommendations.append("资源类型较多，可能影响求解性能")

    if precedence_count == 0:
        recommendations.append("没有发现前置关系，所有工序将并行执行")

    if not recommendations:
        recommendations.append("CSV文件格式良好，可以进行调度优化")

    return recommendations


# 异常处理器
@app.exception_handler(SchedulerError)
async def scheduler_exception_handler(request, exc: SchedulerError):
    """调度器异常处理器"""
    logger.error(
        f"Scheduler error: {exc.message}", extra={"error_code": exc.error_code}
    )
    return JSONResponse(
        status_code=400,
        content={
            "success": False,
            "error": exc.to_dict(),
            "timestamp": get_current_timestamp(),
        },
    )


@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    """HTTP异常处理器"""
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "success": False,
            "error_message": exc.detail,
            "timestamp": get_current_timestamp(),
        },
    )


@app.exception_handler(Exception)
async def general_exception_handler(request, exc):
    """通用异常处理器"""
    logger.error(f"Unexpected error: {str(exc)}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "success": False,
            "error_message": f"系统内部错误: {str(exc)}",
            "timestamp": get_current_timestamp(),
        },
    )


# 启动配置
if __name__ == "__main__":
    uvicorn.run(
        "simplified_api:app", host="0.0.0.0", port=8000, reload=True, log_level="info"
    )
